using System;
using System.Text;
using System.Threading;

using Gtk;

using Gazebo.Core;

namespace Gazebo {
	public partial class MainWindow: Gtk.Window
	{
        private Client client = null;
        
        private IcsConsole console;
        
	    public MainWindow (): base (Gtk.WindowType.Toplevel)
	    {
	        Build ();
            
            console = new IcsConsole();
            
            mainNotebook.AppendPage(console, new Label("Console"));
            console.Show();
            
            console.AppendInformation("Gazebo 0.0.0\n(c) 2009 Chris Howie\n---");
            commandEntry.GrabFocus();
	    }
	    
	    protected void OnDeleteEvent (object sender, DeleteEventArgs a)
	    {
            if (client != null) {
                client.DisposeSilently();
            }
            
	        Application.Quit ();
	        a.RetVal = true;
	    }

	    protected virtual void OnConnectActionActivated (object sender, System.EventArgs e)
	    {
            if (client != null) {
                client.DisposeSilently();
            }
            
            DisconnectAction.Sensitive = true;
            
            INetworkFilterFactory nFilter = CorePreferences.Instance.NetworkFilterFactory;
            
            client = new Client(CorePreferences.Instance.ServerHostname,
                                CorePreferences.Instance.ServerPort,
                                nFilter);
            
            client.ChunkRead += Extras.OnMainLoop<ChunkReadEventArgs>(ProcessChunk);
            client.ConnectionClosed += Extras.OnMainLoop(OnDisconnected);
            
            client.Start();
            
            string message;
            
            if (nFilter == null) {
                message = "\nConnected without any filter.  This means you are not using Timeseal and you will be penalized for network lag between your computer and the server.  Please check the Gazebo documentation for information on setting up Timeseal.";
            } else {
                message = string.Format("\nConnected using filter \"{0}\".", nFilter.Label);
            }
            
            console.AppendInformation(message);
        }
        
        private void ProcessChunk(object o, ChunkReadEventArgs e) {
            ((IChunkConsumer) console).ConsumeChunk(e.Chunk);
            
            foreach (IChunkConsumer consumer in AddinUtilities.GetExtensionObjects<IChunkConsumer>("/Gazebo/Client/ChunkConsumer")) {
                consumer.ConsumeChunk(e.Chunk);
            }
        }

        protected virtual void OnCommandEntryActivated (object sender, System.EventArgs e)
        {
            if (client == null) {
                return;
            }
            
            client.WriteLine(commandEntry.Text);
            console.AppendSentLine(commandEntry.Text);
            
            commandEntry.Text = "";
        }

        protected virtual void OnDisconnectActionActivated (object sender, System.EventArgs e)
        {
            if (client != null) {
                client.Dispose();
            }
        }
        
        private void OnDisconnected(object sender, EventArgs e)
        {
            client = null;
            DisconnectAction.Sensitive = false;
            
            console.AppendInformation("\n--- Disconnected");
        }

        protected virtual void OnPreferencesActionActivated(object sender, System.EventArgs e)
        {
            PreferencesDialog dialog = new PreferencesDialog();
            dialog.TransientFor = this;
            
            try {
                dialog.Run();
            } finally {
                dialog.Destroy();
            }
        }
    }
}